// ---------------------------------------------------------------------
// test.c
// ---------------------------------------------------------------------

#include <pthread.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <mqueue.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
#include "config.h"
#include "simulation.h"
#include "erreur.h"

static void * ThreadTest();


int main()
{
	mq_unlink (BAL_versErreur);
	struct mq_attr lesAttr={0,1,sizeof(MSG_versErreur),0};
	pthread_t threadErreur, threadTest;
	mqd_t queue_handle_versErreur;
	queue_handle_versErreur=mq_open(BAL_versErreur,O_CREAT|O_RDWR,0777, &lesAttr);
	if (queue_handle_versErreur == -1)
	{
		perror ("[TEST] Error Opening MQ BAL_versErreur:");
	}
	
	// Vers archivage
	mq_unlink (BAL_versArchivage);
	struct mq_attr lesAttrArch={0,1,sizeof(MSG_versArchivage),0};
	mqd_t queue_handle_versArchivage;
	queue_handle_versArchivage=mq_open(BAL_versArchivage,O_CREAT|O_RDWR,0777, &lesAttrArch);
	if (queue_handle_versArchivage == -1)
	{
		perror ("[TEST] Error Opening MQ queue_handle_versArchivage:");
	}
	
	// Vers Ecriture
	mq_unlink (BAL_versEcriture);
	struct mq_attr lesAttrEcri={0,1,sizeof(MSG_versEcriture),0};
	mqd_t queue_handle_versEcriture;
	queue_handle_versEcriture=mq_open(BAL_versEcriture,O_CREAT|O_RDWR,0777, &lesAttrEcri);
	if (queue_handle_versEcriture == -1)
	{
		perror ("[TEST] Error Opening MQ queue_handle_versEcriture:");
	}
	
	
	// Vers MSG_decisionErreur
	mq_unlink (BAL_decisionErreur);
	struct mq_attr lesAttrDec={0,1,sizeof(MSG_decisionErreur),0};
	mqd_t queue_handle_decisionErreur;
	queue_handle_decisionErreur=mq_open(BAL_decisionErreur,O_CREAT|O_RDWR,0777, &lesAttrDec);
	if (queue_handle_decisionErreur == -1)
	{
		perror ("[TEST] Error Opening MQ queue_handle_decisionErreur:");
	}
	
	
	// Vers MSG_retErreur
	mq_unlink (BAL_retErreur);
	struct mq_attr lesAttrRet={0,1,sizeof(MSG_retErreur),0};
	mqd_t queue_handle_retErreur;
	queue_handle_retErreur=mq_open(BAL_retErreur,O_CREAT|O_RDWR,0777, &lesAttrRet);
	if (queue_handle_retErreur == -1)
	{
		perror ("[TEST] Error Opening MQ queue_handle_retErreur:");
	}
	
	
	pthread_create (&threadTest,    NULL, &ThreadTest,    NULL);
	pthread_create (&threadErreur, NULL, &Erreur, NULL);
	
	pthread_join (threadErreur,    NULL);
	pthread_join (threadTest,    NULL);
	mq_close(queue_handle_versErreur);
	mq_unlink(BAL_versErreur);
	mq_close(queue_handle_versArchivage);
	mq_unlink(BAL_versArchivage);
	mq_close(queue_handle_versEcriture);
	mq_unlink(BAL_versEcriture);
	mq_close(queue_handle_decisionErreur);
	mq_unlink(BAL_decisionErreur);
	return 0;
}

static void * ThreadTest ()
{
	mqd_t queue_handle_versErreur, queue_handle_versArchivage, queue_handle_retErreur, queue_handle_versEcriture, queue_handle_decisionErreur;
	
	
	queue_handle_versErreur =  mq_open(BAL_versErreur,O_WRONLY);
	if (queue_handle_versErreur == -1)
	{
		perror ("[TEST] Error Opening MQ BAL_versErreur:");
	}
	
	queue_handle_versArchivage =  mq_open(BAL_versArchivage,O_RDONLY);
	if (queue_handle_versArchivage == -1)
	{
		perror ("[TEST] Error Opening MQ BAL_versArchivage:");
	}
	
	queue_handle_versEcriture =  mq_open(BAL_versEcriture,O_RDONLY);
	if (queue_handle_versEcriture == -1)
	{
		perror ("[TEST] Error Opening MQ BAL_versEcriture:");
	}
	
	queue_handle_decisionErreur =  mq_open(BAL_decisionErreur,O_WRONLY);
	if (queue_handle_decisionErreur == -1)
	{
		perror ("[TEST] Error Opening MQ BAL_decisionErreur:");
	}
	
	queue_handle_retErreur =  mq_open(BAL_retErreur,O_RDONLY);
	if (queue_handle_retErreur == -1)
	{
		perror ("[TEST] Error Opening MQ BAL_retErreur:");
	}
	
	
	
	printf("[TEST] Envoie message erreur \n");
	MSG_versErreur messageErreurRecu;
	messageErreurRecu.source = T_AU;
	messageErreurRecu.message = 7;
	messageErreurRecu.heure = 6;
	messageErreurRecu.numLot = 5;
	messageErreurRecu.cartonEnCours = 4;
	if (0 != mq_send (queue_handle_versErreur, (const char*) &messageErreurRecu, sizeof(MSG_versErreur), 2))
	{
		perror ("[TEST] Sending to BAL_versArchivage:");
	}
	
	
	// Attente du dépot d'un message d'erreur dans la boite aux lettres
	printf("[TEST] Attente du message archivage \n");
	MSG_versArchivage messageArchivage;
	int bytes_read = mq_receive(queue_handle_versArchivage, (char*) &messageArchivage, sizeof(MSG_versArchivage), NULL);

	if (bytes_read == -1)
	{
		perror("[TEST] Failed to recieve BAL_versArchivage:");
	}
	printf("[TEST] MessageVersArchivage : Source %d, Message %d, numLot %d, cartonEnCours %d, type %d \n", messageArchivage.source, messageArchivage.message, messageArchivage.numLot, messageArchivage.cartonEnCours, messageArchivage.type); 
	
	
	// Attente du dépôt d'un message dialogue opérateur
	printf("[TEST] Attente de la demande dialogue opérateur \n");
	MSG_versEcriture messageEcriture;
	bytes_read = mq_receive(queue_handle_versEcriture, (char*) &messageEcriture, sizeof(MSG_versEcriture), NULL);

	if (bytes_read == -1)
	{
		perror("[TEST] Failed to recieve BAL_versEcriture:");
	}
	printf("[TEST] messageEcriture : type %d, Message %d, numLot %d, cartonEnCours %d \n", messageEcriture.typeMessage, messageEcriture.message, messageEcriture.numLot, messageEcriture.cartonEnCours); 
	
	
	
	// Réponse de l'opérateur
	printf("[TEST] Envoie réponse opérateur \n");
	MSG_decisionErreur messagedecisionErreur;
	messagedecisionErreur.reponse = FIN_APPLI;
	if (0 != mq_send (queue_handle_decisionErreur, (const char*) &messagedecisionErreur, sizeof(MSG_decisionErreur), 2))
	{
		perror ("[TEST] Sending to queue_handle_decisionErreur:");
	}
	
	// Attente du retour Erreur
	printf("[TEST] Attente du retour Erreur \n");
	MSG_retErreur messageRetErreur;
	bytes_read = mq_receive(queue_handle_retErreur, (char*) &messageRetErreur, sizeof(MSG_retErreur), NULL);

	if (bytes_read == -1)
	{
		perror("[TEST] Failed to recieve BAL_retErreur:");
	}
	printf("[TEST] messageRetErreur : dest %d, reponse %d\n", messageRetErreur.dest, messageRetErreur.reponse); 
	
	
	
	mq_close (queue_handle_versErreur);
	mq_close (queue_handle_versArchivage);
	mq_close (queue_handle_versEcriture);
	mq_close (queue_handle_decisionErreur);
	mq_close (queue_handle_retErreur);
}

